package cn.chenfeifx.core.common;

import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.value.WritableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.util.Duration;

import java.util.ArrayList;
import java.util.List;

/**
 * 简单动画工具类
 */
public class AnimationUtils {

    /**
     * 并行动画
     * <br/>
     * 注意：target，startValue，endValue 长度必须一致
     *
     * @param duration        执行时间，默认从0开始
     * @param targets
     * @param startValue      开始值
     * @param endValue        结束值
     * @param finishedHandler 动画结束事件
     * @param <T>
     * @return
     */
    public static <T> Timeline parallel(Duration duration,
                                        WritableValue<T>[] targets,
                                        T[] startValue,
                                        T[] endValue,
                                        EventHandler<ActionEvent> finishedHandler) {
        return parallel(duration, targets, startValue, endValue, finishedHandler, false, Duration.ZERO);
    }

    /**
     * 并行动画
     * <br/>
     * 注意：target，startValue，endValue 长度必须一致
     *
     * @param duration        执行时间，默认从0开始
     * @param targets
     * @param startValue      开始值
     * @param endValue        结束值
     * @param finishedHandler 动画结束事件
     * @param autoReverse     自动倒带
     * @param <T>
     * @return
     */
    public static <T> Timeline parallel(Duration duration,
                                        WritableValue<T>[] targets,
                                        T[] startValue,
                                        T[] endValue,
                                        EventHandler<ActionEvent> finishedHandler,
                                        boolean autoReverse) {
        return parallel(duration, targets, startValue, endValue, finishedHandler, autoReverse, Duration.ZERO);
    }

    /**
     * 并行动画
     * <br/>
     * 注意：target，startValue，endValue 长度必须一致
     *
     * @param duration        执行时间，默认从0开始
     * @param targets
     * @param startValue      开始值
     * @param endValue        结束值
     * @param finishedHandler 动画结束事件
     * @param autoReverse     自动倒带
     * @param pause           动画完成之前的暂停时间*2
     * @param <T>
     * @return
     */
    public static <T> Timeline parallel(Duration duration,
                                        WritableValue<T>[] targets,
                                        T[] startValue,
                                        T[] endValue,
                                        EventHandler<ActionEvent> finishedHandler,
                                        boolean autoReverse,
                                        Duration pause) {
        final Timeline timeline = new Timeline();
        List<KeyValue> startKeyValues = new ArrayList<>();
        List<KeyValue> endKeyValues = new ArrayList<>();
        for (int i = 0; i < targets.length; i++) {
            WritableValue<T> writableValue = targets[i];
            startKeyValues.add(new KeyValue(writableValue, startValue[i], Interpolator.LINEAR));
            endKeyValues.add(new KeyValue(writableValue, endValue[i], Interpolator.LINEAR));
        }
        KeyFrame startKeyFrame = new KeyFrame(Duration.ZERO, startKeyValues.toArray(new KeyValue[0]));
        KeyFrame endKeyFrame = new KeyFrame(duration, endKeyValues.toArray(new KeyValue[0]));
        timeline.getKeyFrames().setAll(startKeyFrame, endKeyFrame);
        if (pause.toMillis() != 0) {
            timeline.getKeyFrames().add(new KeyFrame(duration.add(pause))); // 暂停动画
        }
        timeline.setCycleCount(autoReverse ? 2 : 1);
        timeline.setAutoReverse(autoReverse);
        timeline.setOnFinished(finishedHandler);
        return timeline;
    }

}
